using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Linq;

using MvcCms.Data;

namespace MvcCmsOptIn.Data
{
    public class EntityOptInRepository : IOptInRepository
    {
        #region Constructors
        private readonly MvcCmsEntities _entities;

        public EntityOptInRepository(IEntitiesProvider entitiesProvider)
        {
            _entities = entitiesProvider.GetEntityContext();
        }
        #endregion

        #region Subscriber Methods
        public void DeleteSubscriber(int subscriberId)
        {
            var originalSubscriber = GetSubscriber(subscriberId);

            _entities.DeleteObject(originalSubscriber);
            _entities.SaveChanges();
        }

        public void DeleteSubscriberList(int subscriberListId)
        {
            var originalSubscriberList = GetSubscriberList(subscriberListId);

            _entities.DeleteObject(originalSubscriberList);
            _entities.SaveChanges();
        }

        public OptInSubscriber EditSubscriber(OptInSubscriber subscriberToEdit)
        {
            _entities.OptInSubscriberSet.ApplyCurrentValues(subscriberToEdit);
            _entities.SaveChanges();
            return subscriberToEdit;
        }

        public OptInSubscriber GetSubscriber(int subscriberId)
        {
            return (from s in _entities.OptInSubscriberSet
                    .Include("SubscriberLists.List")
                    where s.SubscriberID==subscriberId
                    select s).FirstOrDefault();
        }

        private OptInSubscriberList GetSubscriberList(int subscriberListId)
        {
            return (from s in _entities.OptInSubscriberListSet
                    where s.SubscriberListID == subscriberListId
                    select s).FirstOrDefault();
        }

        public OptInSubscriber GetSubscriber(string email)
        {
            return (from s in _entities.OptInSubscriberSet
                    .Include("SubscriberLists")
                    where s.EMail.ToLower() == email.ToLower()
                    select s).FirstOrDefault();
        }

        public OptInSubscriber CreateSubscriber(OptInSubscriber subscriberToCreate)
        {
            subscriberToCreate.CreateDate = DateTime.Now;
            _entities.OptInSubscriberSet.AddObject(subscriberToCreate);
            _entities.SaveChanges();
            return subscriberToCreate;
        }

        public IEnumerable<OptInSubscriber> ListSubscribers(int portalId)
        {
            return (from c in _entities.OptInSubscriberSet
                    where c.PortalID == portalId
                    orderby c.Name
                    select c);
        }

        public IEnumerable<OptInSubscriberList> ListListsSubscribers(int newsLetterID)
        {
            var newsLetter = (from c in _entities.OptInNewsLetterSet
                                 .Include("Lists")
                                 where c.NewsLetterID == newsLetterID
                                 select c).FirstOrDefault();

            var listIds = newsLetter.Lists.Select(l => l.ListID);

            var listsSubscribers = (from sl in _entities.OptInSubscriberListSet
                                    where listIds.Contains(sl.ListID)
                                    select sl);
            return listsSubscribers;
        }
        public IEnumerable<DTOSubscriber> ListListSubscribers(int listId)
        {
            return (from c in _entities.DTOSubscriberSet
                    where c.ListID==listId
                    select c);
        }
        #endregion

        #region List Methods

        public void DeleteList(int listId)
        {
            var originalList = GetList(listId);

            _entities.DeleteObject(originalList);
            _entities.SaveChanges();
        }

        public OptInList EditList(OptInList listToEdit)
        {
            _entities.OptInListSet.ApplyCurrentValues(listToEdit);
            _entities.SaveChanges();
            return listToEdit;
        }

        public OptInList GetList(int listId)
        {
            return (from s in _entities.OptInListSet
                    .Include("Admin")
                    where s.ListID == listId
                    select s).FirstOrDefault();
        }

        public OptInList CreateList(OptInList listToCreate)
        {
            listToCreate.CreateDate = DateTime.Now;
            _entities.OptInListSet.AddObject(listToCreate);
            _entities.SaveChanges();
            return listToCreate;
        }

        public IEnumerable<OptInListWithCounts> ListListsWithCounts(int portalId)
        {
            return (from c in _entities.OptInListWithCountsSet
                    where c.PortalID == portalId
                    orderby c.ListName
                    select c);
        }

        public IEnumerable<OptInList> ListLists(int portalId)
        {
            return (from c in _entities.OptInListSet
                    where c.PortalID == portalId
                    orderby c.ListName
                    select c);
        }
        #endregion

        #region TrackingLink Methods

        public OptInLinkTracking GetTrackingLink(int linkTrackingID)
        {
            return (from s in _entities.OptInLinkTrackingSet
                    .Include("Admin")
                    where s.LinkTrackingID == linkTrackingID
                    select s).FirstOrDefault();
        }
        public OptInLinkTracking EditTrackingLink(OptInLinkTracking trackingLinkToEdit)
        {
            _entities.OptInLinkTrackingSet.ApplyCurrentValues(trackingLinkToEdit);
            _entities.SaveChanges();
            return trackingLinkToEdit;
        }
        public OptInLinkTracking CreateTrackingLink(OptInLinkTracking linkToCreate)
        {
            linkToCreate.CreateDate = DateTime.Now;
            _entities.OptInLinkTrackingSet.AddObject(linkToCreate);
            _entities.SaveChanges();
            return linkToCreate;
        }

        public void DeleteTrackingLink(int linkId)
        {
            var originalLink = GetTrackingLink(linkId);

            _entities.DeleteObject(originalLink);
            _entities.SaveChanges();
        }
        public IEnumerable<OptInLinkTracking> ListTrackingLinks(int newsLetterId)
        {
            return (from c in _entities.OptInLinkTrackingSet
                    where c.NewsLetterID == newsLetterId
                    orderby c.Name
                    select c);
        }

        #endregion

        #region NewsLetter Methods
        public void DeleteNewsLetter(int newsLetterId)
        {
            var originalNewsLetter = GetNewsLetter(newsLetterId);

            _entities.DeleteObject(originalNewsLetter);
            _entities.SaveChanges();
        }

        public OptInNewsLetter EditNewsLetter(OptInNewsLetter newsLetterToEdit)
        {
            _entities.OptInNewsLetterSet.ApplyCurrentValues(newsLetterToEdit);
            _entities.SaveChanges();
            return newsLetterToEdit;
        }

        public OptInNewsLetter GetNewsLetter(int newsLetterId)
        {
            return (from s in _entities.OptInNewsLetterSet
                    .Include("Admin")
                    .Include("Lists")
                    where s.NewsLetterID == newsLetterId
                    select s).FirstOrDefault();
        }

        public OptInNewsLetter CreateNewsLetter(OptInNewsLetter newsLetterToCreate)
        {
            newsLetterToCreate.CreateDate = DateTime.Now;
            _entities.OptInNewsLetterSet.AddObject(newsLetterToCreate);
            _entities.SaveChanges();
            return newsLetterToCreate;
        }

        public IEnumerable<OptInNewsLetterWithCounts> ListNewsLetters(int portalId)
        {
            return (from c in _entities.OptInNewsLetterWithCountsSet
                    where c.PortalID == portalId
                    orderby c.Name
                    select c);
        }
        #endregion

    }
}